package com.wkhyapp.lm.base;


import android.app.Activity;
import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
import android.os.MessageQueue;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.appcompat.BuildConfig;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Toolbar;
import com.google.gson.Gson;
import com.maning.mndialoglibrary.MProgressDialog;
import com.maning.mndialoglibrary.MToast;
import com.maning.mndialoglibrary.config.MToastConfig;
import com.wkhyapp.lm.utils.StringUtils;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import butterknife.ButterKnife;
/**
 * Created by Administrator on 2018-8-6.
 */

public abstract class BaseActivity extends AppCompatActivity {


    protected Toolbar toolbar;
    protected Context mContext;
    private Toast toast;
    protected String TAG = null;
    public String code;
    protected Gson gson;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.mContext = this;
        gson = new Gson();
        beforeSetContentView();
        setContentView(getLayoutId());
        TAG = getClass().getSimpleName();
        if (BuildConfig.DEBUG) {
            Log.e("", TAG);
        }

        ButterKnife.bind(this);
        initUI();//适配 ，以及将不需要网络请求的UI初始化
        initListener();
        afterCreate();//用来注册监听事件之类，请求数据
    }




    /**
     * 初始化控件，适配 等写这里
     */
    public abstract void initUI();

    protected void beforeSetContentView() {
    }


    protected void translucentStatusBar() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window window = getWindow();
            // Translucent status bar
            window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                    WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

    /**
     * 需要初始化的一些参数 比如取ID 等写在这里
     */
    protected abstract void afterCreate();

    protected abstract int getLayoutId();



    /**
     * 加载动画
     *
     * @param str
     */
    public void showLoad(String str) {
        if(StringUtils.isEmpty(str)){
            str = "正在加载...";
        }
        MProgressDialog.showProgress(this,str);
    }

    public void setBack() {
        if (toolbar != null) {
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    finish();
                }
            });
        }
    }


    public void setBack(View.OnClickListener listener) {
        if (toolbar != null) {
            toolbar.setNavigationOnClickListener(listener);
        }
    }

    /**
     * 关闭加载动画
     */
    public void dismissLoad() {
        if( MProgressDialog.isShowing()){
            MProgressDialog.dismissProgress();
        }

    }


    /**
     * 判断服务是否在运行
     * @param context
     * @param serviceName
     * @return
     * 服务名称为全路径 例如com.ghost.WidgetUpdateService
     */
    public boolean isRunService(Context context, String serviceName) {
        ActivityManager manager = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            Log.d("Service",service.service.getClassName()+"");
            if (serviceName.equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }



    /**
     * 弹出错误toast
     *
     * @param str
     */
    public void setfail(String str) {
        TToast(str);
    }


    public Context getContext() {
        return this;
    }

    /**
     * 需要监听的方法写在这里
     */
    protected abstract void initListener();

    @Override
    protected void onDestroy() {
        super.onDestroy();

    }

    @Override
    public void onResume() {
        super.onResume();

    }


    @Override
    public void onPause() {
        super.onPause();
    }




    /**
     * 参数传递(注：该方法为了方便传参,参数类型有局限性,传递特殊类型时单独构建Intent)
     **/
    public void goTo(Class<?> goToCls, Object... values) {
        goTo(false, goToCls, values);
    }

    /**
     * 参数传递(注：该方法为了方便传参,参数类型有局限性,传递特殊类型时单独构建Intent)
     **/
    public void goTo(boolean finish, Class<?> goToCls, Object... values) {
        Intent intent = new Intent(this, goToCls);

        int i = 0;
        for (Object value : values) {
            Class<?> cls = value.getClass();
            String key = String.valueOf(i);
            if (cls == String.class) {
                intent.putExtra(key, (String) value);
            } else if (value instanceof Serializable) {
                intent.putExtra(key, (Serializable) value);
            } else if (cls == int[].class) {
                intent.putExtra(key, (int[]) value);
            } else if (cls == long[].class) {
                intent.putExtra(key, (long[]) value);
            } else if (cls == boolean[].class) {
                intent.putExtra(key, (boolean[]) value);
            } else if (cls == float[].class) {
                intent.putExtra(key, (float[]) value);
            } else if (cls == double[].class) {
                intent.putExtra(key, (double[]) value);
            } else if (cls == char[].class) {
                intent.putExtra(key, (char[]) value);
            } else if (cls == String[].class) {
                intent.putExtra(key, (String[]) value);
            } else if (cls == Bundle.class) {
                intent.putExtra(key, (Bundle) value);
            } else {
                throw new RuntimeException("不支持参数类型: " + cls.getSimpleName());
            }
            i++;
        }
        startActivity(intent);
        if (finish) {
            finish();
        }
    }

    /**
     * 参数传递(注：该方法为了方便传参,参数类型有局限性,传递特殊类型时单独构建Intent)
     **/
    public void goToForResult(Class<?> goToCls, Object... values) {
        goToForResult(false, goToCls, values);
    }

    /**
     * 参数传递(注：该方法为了方便传参,参数类型有局限性,传递特殊类型时单独构建Intent)
     **/
    public void goToForResult(boolean finish, Class<?> goToCls, Object... values) {
        Intent intent = new Intent(this, goToCls);
        int i = 0;
        for (Object value : values) {
            Class<?> cls = value.getClass();
            String key = String.valueOf(i);
            if (cls == String.class) {
                intent.putExtra(key, (String) value);
            } else if (value instanceof Serializable) {
                intent.putExtra(key, (Serializable) value);
            } else if (cls == int[].class) {
                intent.putExtra(key, (int[]) value);
            } else if (cls == long[].class) {
                intent.putExtra(key, (long[]) value);
            } else if (cls == boolean[].class) {
                intent.putExtra(key, (boolean[]) value);
            } else if (cls == float[].class) {
                intent.putExtra(key, (float[]) value);
            } else if (cls == double[].class) {
                intent.putExtra(key, (double[]) value);
            } else if (cls == char[].class) {
                intent.putExtra(key, (char[]) value);
            } else if (cls == String[].class) {
                intent.putExtra(key, (String[]) value);
            } else if (cls == Bundle.class) {
                intent.putExtra(key, (Bundle) value);
            } else {
                throw new RuntimeException("不支持参数类型: " + cls.getSimpleName());
            }
            i++;
        }
        startActivityForResult(intent, 0);
        if (finish) {
            finish();
        }
    }


    /**
     * 获取控件信息
     */
    public String getViewValue(View view) {
        if (view instanceof EditText) {
            return ((EditText) view).getText().toString();
        } else if (view instanceof TextView) {
            return ((TextView) view).getText().toString();
        } else if (view instanceof CheckBox) {
            return ((CheckBox) view).getText().toString();
        } else if (view instanceof RadioButton) {
            return ((RadioButton) view).getText().toString();
        } else if (view instanceof Button) {
            return ((Button) view).getText().toString();
        }
        return null;
    }

    @Override
    public boolean onSupportNavigateUp() {
        onBackPressed();
        return true;
    }


    /**
     * 显示控件
     *
     * @param v
     */
    public void VISIBLE(View v) {
        v.setVisibility(View.VISIBLE);
    }

    /**
     * 隐藏控件
     *
     * @param v
     */
    public void GONE(View v) {
        v.setVisibility(View.GONE);
    }

    public void INVISIBLE(View v) {
        v.setVisibility(View.INVISIBLE);
    }


    protected void TToast(String msg) {
        MToast.makeTextShort(mContext, msg);
    }
    protected void TToastLong(String msg) {
        MToast.makeTextLong(mContext, msg);
    }


    public static boolean isEmpty(Object... objs) {
        for (Object obj : objs) {
            if (obj == null) {
                return true;
            } else if (obj instanceof String && obj.equals("")) {
                return true;
            }
        }
        return false;
    }


    static class ReferenceCleaner
            implements MessageQueue.IdleHandler, View.OnAttachStateChangeListener,
            ViewTreeObserver.OnGlobalFocusChangeListener {

        private final InputMethodManager inputMethodManager;
        private final Field mHField;
        private final Field mServedViewField;
        private final Method finishInputLockedMethod;

        ReferenceCleaner(InputMethodManager inputMethodManager, Field mHField, Field mServedViewField,
                         Method finishInputLockedMethod) {
            this.inputMethodManager = inputMethodManager;
            this.mHField = mHField;
            this.mServedViewField = mServedViewField;
            this.finishInputLockedMethod = finishInputLockedMethod;
        }

        @Override
        public void onGlobalFocusChanged(View oldFocus, View newFocus) {
            if (newFocus == null) {
                return;
            }
            if (oldFocus != null) {
                oldFocus.removeOnAttachStateChangeListener(this);
            }
            Looper.myQueue().removeIdleHandler(this);
            newFocus.addOnAttachStateChangeListener(this);
        }

        @Override
        public void onViewAttachedToWindow(View v) {
        }

        @Override
        public void onViewDetachedFromWindow(View v) {
            v.removeOnAttachStateChangeListener(this);
            Looper.myQueue().removeIdleHandler(this);
            Looper.myQueue().addIdleHandler(this);
        }

        @Override
        public boolean queueIdle() {
            clearInputMethodManagerLeak();
            return false;
        }

        private void clearInputMethodManagerLeak() {
            try {
                Object lock = mHField.get(inputMethodManager);
                // This is highly dependent on the InputMethodManager implementation.
                synchronized (lock) {
                    View servedView = (View) mServedViewField.get(inputMethodManager);
                    if (servedView != null) {

                        boolean servedViewAttached = servedView.getWindowVisibility() != View.GONE;

                        if (servedViewAttached) {
                            // The view held by the IMM was replaced without a global focus change. Let's make
                            // sure we get notified when that view detaches.

                            // Avoid double registration.
                            servedView.removeOnAttachStateChangeListener(this);
                            servedView.addOnAttachStateChangeListener(this);
                        } else {
                            // servedView is not attached. InputMethodManager is being stupid!
                            Activity activity = extractActivity(servedView.getContext());
                            if (activity == null || activity.getWindow() == null) {
                                // Unlikely case. Let's finish the input anyways.
                                finishInputLockedMethod.invoke(inputMethodManager);
                            } else {
                                View decorView = activity.getWindow().peekDecorView();
                                boolean windowAttached = decorView.getWindowVisibility() != View.GONE;
                                if (!windowAttached) {
                                    finishInputLockedMethod.invoke(inputMethodManager);
                                } else {
                                    decorView.requestFocusFromTouch();
                                }
                            }
                        }
                    }
                }
            } catch (Exception unexpected) {
                Log.e("IMMLeaks", "Unexpected reflection exception", unexpected);
            }
        }

        private Activity extractActivity(Context context) {
            while (true) {
                if (context instanceof Application) {
                    return null;
                } else if (context instanceof Activity) {
                    return (Activity) context;
                } else if (context instanceof ContextWrapper) {
                    Context baseContext = ((ContextWrapper) context).getBaseContext();
                    // Prevent Stack Overflow.
                    if (baseContext == context) {
                        return null;
                    }
                    context = baseContext;
                } else {
                    return null;
                }
            }
        }

    }


}